package com.whty.cms.filewps.util;

import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.Proxy;
import java.net.URL;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

public class HttpClient {
	
	private static Logger logger = LogManager.getLogger(HttpClient.class);

	private Integer connectTimeOut = 15000;
	
	private Integer readTimeOut = 15000;
	
	private HttpURLConnection connection;
	
	public HttpClient(String urlAddr) throws MalformedURLException {
		this(urlAddr, null);
	}
	
	public HttpClient(URL url) {
		this(url, null);
	}
	
	public HttpClient(String urlAddr, Proxy proxy) throws MalformedURLException {
		this(new URL(urlAddr), proxy);
	}
	
	public HttpClient(URL url, Proxy proxy) {
		if (url == null) {
			throw new IllegalArgumentException("url can not be null.");
		}
		try {
			if (proxy != null) {
				connection = (HttpURLConnection) url.openConnection(proxy);
			} else {
				connection = (HttpURLConnection) url.openConnection();
			}
			connection.setConnectTimeout(connectTimeOut);
			connection.setReadTimeout(readTimeOut);
		} catch(Exception ex) {
			logger.error(ex.getMessage());
			throw new RuntimeException(ex);
		}
	}
	
	public String doGet() throws Exception {
		String result;
		ByteArrayOutputStream resultOut = new ByteArrayOutputStream();
		BufferedInputStream resultIn = null;
		try {
			String HTTP_GET = "GET";
			connection.setRequestMethod(HTTP_GET);
			connection.connect();
			byte[] buff = new byte[10240];
			int len;
			
			resultIn = new BufferedInputStream(connection.getInputStream());
			while ((len = resultIn.read(buff)) > 0) {
				resultOut.write(buff, 0, len);
			}
			resultOut.close();
			result = resultOut.toString("UTF-8");
		} finally {
			resultOut.close();
			if (resultIn != null) resultIn.close();
		}
		
		return result;
	}
	
	public String doPost(byte[] contents) throws Exception {
		String result;
		BufferedOutputStream paramOut = null;
		ByteArrayInputStream paramIn = new ByteArrayInputStream(contents);
		ByteArrayOutputStream resultOut = new ByteArrayOutputStream();
		BufferedInputStream resultIn = null;
		try {
			String HTTP_POST = "POST";
			connection.setRequestMethod(HTTP_POST);
			connection.setDoOutput(true);
			String contentType = connection.getRequestProperty("Content-Type");
			if (StringUtils.isEmpty(contentType)) {
				connection.setRequestProperty("Content-Type", "application/json;charset=utf-8");
			}
			connection.setRequestProperty("Content-Length", String.valueOf(contents.length));
			connection.connect();
			byte[] buff = new byte[10240];
			int len;
			paramOut = new BufferedOutputStream(connection.getOutputStream());
			while ((len = paramIn.read(buff)) > 0) {
				paramOut.write(buff, 0, len);
			}
			paramOut.close();
			
			resultIn = new BufferedInputStream(connection.getInputStream());
			while ((len = resultIn.read(buff)) > 0) {
				resultOut.write(buff, 0, len);
			}
			resultOut.close();
			result = resultOut.toString("UTF-8");
		} finally {
			if (paramOut != null) paramOut.close();
			paramIn.close();
			resultOut.close();
			if (resultIn != null) resultIn.close();
		}
		
		return result;
	}
	
	public String doPost(String content) throws Exception {
		byte[] contents = new byte[0];
		if (StringUtils.isNotEmpty(content)) {
			contents = content.getBytes("UTF-8");
		}
		return doPost(contents);
	}
	
	public String doPost(Map<String, String> requestParams) throws Exception {
		StringBuilder content = new StringBuilder();
		if (requestParams != null && !requestParams.isEmpty()) {
			Set<Entry<String, String>> entrySet = requestParams.entrySet();
			for (Entry<String, String> entry : entrySet) {
				content.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
			}
			content.delete(content.length() - 1, content.length());
			logger.info("requestParams:" + content.toString());
		}
		return doPost(content.toString());
	}
	
	public void setRequestProperty(String key, String value) {
		connection.setRequestProperty(key, value);
	}

	public Integer getConnectTimeOut() {
		return connectTimeOut;
	}

	public void setConnectTimeOut(Integer connectTimeOut) {
		this.connectTimeOut = connectTimeOut;
		connection.setConnectTimeout(connectTimeOut);
	}

	public Integer getReadTimeOut() {
		return readTimeOut;
	}

	public void setReadTimeOut(Integer readTimeOut) {
		this.readTimeOut = readTimeOut;
		connection.setReadTimeout(readTimeOut);
	}

	public HttpURLConnection getConnection() {
		return connection;
	}

	public void setConnection(HttpURLConnection connection) {
		this.connection = connection;
	}

	/**
	 * 获取token
	 *
	 * @return
	 * @throws Exception
	 */
	public static String getAccessToken(String methodUrl) {
		String accessToken = "";
		String appId = "46948d2bbff0f123aec22ad44c2586ab";
		String appKey = "5E76DF1702525sfgB138A017F04DC586";
		//String methodUrl = SysConf.getString("open.api.prefix");
		if(StringUtils.isNotBlank(appId) && StringUtils.isNotBlank(appKey) && StringUtils.isNotBlank(methodUrl)){
			try {
				long timeStamp = System.currentTimeMillis();
				String paramValues = appId + appKey + timeStamp;
				byte[] hmacSHA = EncryptionUtils.getHmacSHA1(paramValues, appKey);
				String digest = EncryptionUtils.bytesToHexString(hmacSHA);
				String keyInfo = digest.toUpperCase();
				JSONObject param = new JSONObject();
				param.put("appid", appId);
				param.put("keyinfo", keyInfo);
				param.put("timeStamp", timeStamp);
				logger.info("通过调用接口获取accessToken,url:"+methodUrl+"/apigateway/getAccessToken");
				logger.info("通过调用接口获取accessToken,param:"+param);
				String resp = new HttpClient(new URL(methodUrl+"/apigateway/getAccessToken")).doPost(param.toString());
				logger.info("通过调用接口获取accessToken,返回结果:"+resp);
				JSONObject result = JSONObject.fromObject(resp);
				if ("000000".equals(result.optString("retCode"))) {
					if (result.has("tokenInfo")) {
						JSONObject data = JSONObject.fromObject(result.get("tokenInfo"));
						if (data.has("accessToken")) {
							accessToken = data.getString("accessToken");
						}
					}
				}
			} catch (Exception e) {
				logger.error("",e);
			}
			return accessToken;

		}else{
			return accessToken;
		}

	}
}
